package response

import (
	"gitee.com/golang-lib/go-framework/ginx"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"net/http"
)

const (
	OK                     = "ok"
	ParameterError         = "参数错误"
	RequestError           = "请求错误"
	SystemError            = "服务器出错了"
	OperationTooFrequently = "操作过于频繁"
	SendFail               = "发送失败"
	VerificationFail       = "验证失败"
	CreateFail             = "上传失败"
	ModifyFail             = "修改失败"
	DeleteFail             = "删除失败"
	UploadFail             = "上传失败"
	PageOrSizeError        = "页码或请求数量错误"
	TooManyRequests        = "请求数量过多"
)

type Result struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

type PageData struct {
	List     any `json:"list"`
	Page     int `json:"page"`
	pageSize int `json:"pageSize"`
	Pages    int `json:"pages"`
	Total    int `json:"total"`
}

type PageInfo struct {
	Page  int `json:"page"`
	Size  int `json:"size"`
	Pages int `json:"pages"`
	Total int `json:"total"`
}

type PageResult struct {
	Result
	PageInfo PageInfo `json:"pageInfo"`
}

func Success(ctx *gin.Context) {
	response(ctx, http.StatusOK, http.StatusOK, nil, "")
}

func SuccessWithData(ctx *gin.Context, data any) {
	response(ctx, http.StatusOK, http.StatusOK, data, "")
}

func Ok(ctx *gin.Context) {
	response(ctx, http.StatusOK, http.StatusOK, nil, "请求成功")
}

func OkWithData(ctx *gin.Context, data interface{}) {
	response(ctx, http.StatusOK, http.StatusOK, data, "请求成功")
}

func OkPageData(ctx *gin.Context, data interface{}) {
	ctx.JSON(http.StatusOK, data)
}

func SuccessPage(ctx *gin.Context, page, size, total int, list interface{}) {
	pages := CalculatePage(int(total), size)
	pageResult := &Result{
		Code: 200,
		Data: PageData{List: list, Page: page, pageSize: size, Pages: pages, Total: int(total)},
	}
	ctx.JSON(http.StatusOK, pageResult)
}

func ClientError(ctx *gin.Context, err error) {
	if errs, ok := err.(validator.ValidationErrors); ok {
		ctx.JSON(http.StatusOK, gin.H{"code": 400, "message": ginx.GetValidationErrors(errs)})
	} else {
		ctx.JSON(http.StatusOK, gin.H{"code": 400, "message": err.Error()})
	}
}

func (r *Result) IsSuccess() bool {
	return r.Code == http.StatusOK
}

func CalculatePage(total, size int) int {
	if size == 0 {
		return 0
	}
	return (total + size - 1) / size
}

func Error(ctx *gin.Context, err error) {
	response(ctx, http.StatusOK, 500, nil, err.Error())
}

func Fail(ctx *gin.Context, code int, message string) {
	response(ctx, http.StatusOK, code, nil, message)
}

func response(ctx *gin.Context, httpStatus int, code int, data any, message string) {
	ctx.JSON(httpStatus, gin.H{"code": code, "data": data, "message": message})
}
